home *** CD-ROM | disk | FTP | other *** search
/ PD Collection CD 1 / PD Collection CD 1.iso / programer2 / euclidlib / c / ewindow < prev    next >
Text File  |  1992-04-21  |  19KB  |  632 lines

  1. /**** ewindow.c ****/
  2. /* By Paul Field
  3.  * See !ReadMe file for distribution/modification restrictions
  4.  */
  5.  
  6. #include "ewindow.h"
  7.  
  8. #include <assert.h>
  9. #include <limits.h>
  10. #include <stdio.h>
  11. #include "cache.h"
  12. #include "edraw.h"
  13. #include "esprite.h"
  14. #include "alarm.h"
  15. #include "bbc.h"
  16. #include "colourtran.h"
  17. #include "flex.h"
  18. #include "sprite.h"
  19. #include "template.h"
  20. #include "werr.h"
  21. #include "wimpt.h"
  22. #include "win.h"
  23.  
  24. /* Patch to make heap calls look like flex calls */
  25. #include "heap.h"
  26. #define flex_alloc(a,s) ((*(a) = heap_alloc(s)) != NULL)
  27. #define flex_free(a)    do{ heap_free(*a); *a = NULL;}while(FALSE)
  28.  
  29.  
  30. /**** #defines for werr() ****/
  31. #define ERR_NonFatal 0
  32. #define ERR_Fatal    1
  33.  
  34.  
  35. /* I may alter all the BOOLs in the structure to be bits in an integer - 
  36.  * this will save 20bytes/window at the expense of slightly more processing time.
  37.  */
  38.  
  39. struct ewindow_str
  40.  { wimp_w           handle;
  41.    const char       *title;
  42.    ewindow_closefn  closefn;
  43.    void             *closehandle;
  44.    wimp_box         workarea;
  45.    edraw_info       *info;
  46.    unsigned int     timeout;       /* Time spent drawing each section */
  47.    unsigned int     drawgap;       /* Gap between drawing sections */
  48.    void             *cache;        /* Address of drawing cache (may == structure) */
  49.    BOOL             sprite;        /* If TRUE window redraws with a sprite if possible */
  50.    ewindow_spritemode mode;        /* Mode of the sprite */
  51.    sprite_area      *area;         /* Sprite area containing window sprite */
  52.                                    /* - NULL if no sprite                  */
  53.    BOOL             drawspritewait;/* TRUE if waiting for cache before draw starts */
  54.    BOOL             firsttime;     /* TRUE if 'drawing' but none drawn yet */
  55.    BOOL             drawing;       /* True if the sprite is still being drawn */
  56.    unsigned int     currenty;      /* Current Y Position of drawing */
  57.    BOOL             redrawwait;    /* TRUE if window is waiting to be redrawn */
  58.    BOOL             freesprite;    /* TRUE -> sprite memory freed on close */
  59.  };
  60.  
  61. /*************************************************************************************
  62. Conditions that should be true given that certain flags or tests are true.
  63. Alarms and processes only concern the window that the test applies to.
  64.  
  65. Given the window is drawing into a sprite :
  66. Conditions that must be true :
  67.   sprite
  68.   area != NULL
  69.  
  70. ----------------+-------+-------------------+
  71.                 |'draw' |  'draw' process   |
  72. Test/Flag       | alarm | pending | running |
  73. ----------------+-------+---------+---------+
  74. drawspritewait  |   N   |    Y    |    N    |
  75. !drawspritewait |   ?   |    N    |    N    |
  76. drawing         |   Y   |    N    |    Y    |
  77. !drawing        |   N   |    N    |    N    |
  78. ----------------+-------+---------+---------+
  79.  
  80. NOTES:
  81.  drawspritewait and drawing should not be TRUE together
  82.  redrawwait should always be FALSE
  83.  
  84. **************************************************************************************
  85.  
  86. Given the window is not drawing into a sprite :
  87. Conditions that must be true :
  88.   area == NULL
  89.  
  90. ---------------+-------+-------------------+
  91.                | redraw| 'redraw' process  |
  92. Test/Flag      | alarm | pending | running |
  93. ---------------+-------+---------+---------+
  94. redrawwait     |   N   |    Y    |    N    |
  95. !redrawwait    |   N   |    N    |    N*   |  * - Except during the actual redraw code
  96. ---------------+-------+---------+---------+
  97. NOTES:
  98.  drawspritewait and drawing should always be FALSE
  99.  
  100. **************************************************************************************/
  101.  
  102. /* Tentative process definition (I may make 'process' a data type and provide a
  103.  * module to handle processes).
  104.  *   start     - Called to start the process
  105.  *   finish    - Called to finish a running process
  106.  *   setup     - Starts the process waiting for the resource
  107.  *   removeall - Removes all copies of process from the waiting queue and terminates
  108.  *               process if it is currently running
  109.  *
  110.  * May also have process types :
  111.  *   one   - only one of the process may be queuing at a time.
  112.  *   many  - several of the process may be queueing.
  113.  */
  114.  
  115.  
  116.  
  117. static void ewindow_redrawsprite(ewindow ew);
  118. static void ewindow_redrawloopsprite(ewindow ew, wimp_redrawstr *rect, BOOL morerects);
  119. static void ewindow_makesprite(ewindow ew);
  120. static void ewindow_drawsprite(ewindow ew);
  121. static void ewindow_removesprite(ewindow ew);
  122. static void ewindow_spritedrawstart(void *d, void *handle);
  123. static void ewindow_spritedrawcontinue(int time, void *handle);
  124. static void ewindow_spritedrawfinish(ewindow ew);
  125. static void ewindow_spritedrawsetup(ewindow ew);
  126. static void ewindow_spritedrawremoveall(ewindow ew);
  127. static void ewindow_euclidupdate(ewindow ew);
  128. static void ewindow_redrawloopeuclid(ewindow ew, wimp_redrawstr *rect, BOOL morerects,
  129.                                                                        BOOL update);
  130. static void ewindow_redrawloopeuclidcacheok(ewindow ew, wimp_redrawstr *rect,
  131.                                             BOOL morerects);
  132. static void ewindow_delayedredrawstart(void *d, void *handle);
  133. static void ewindow_delayedredrawsetup(ewindow ew);
  134. static void ewindow_delayedredrawremoveall(ewindow ew);
  135. static void ewindow_redrawerror(ewindow ew);
  136. static void ewindow_redraw(ewindow ew);
  137. static void ewindow_redrawloop(ewindow ew, wimp_redrawstr *rect, BOOL more, BOOL update);
  138. static void ewindow_handler(wimp_eventstr *e, void *info);
  139. static BOOL ewindow_unknownhandler(wimp_eventstr *e, void *info);
  140.  
  141.  
  142. /******* Code for sprite-drawn windows *******/
  143.  
  144. static void ewindow_redrawsprite(ewindow ew)
  145.  { wimp_redrawstr r;
  146.    BOOL           more;
  147.  
  148.    assert(ew->area);
  149.    r.w = ew->handle;
  150.    r.box = ew->workarea;
  151.    wimpt_noerr(wimp_update_wind(&r, &more));
  152.    ewindow_redrawloopsprite(ew, &r, more);
  153.  }
  154.  
  155.  
  156. static void ewindow_redrawloopsprite(ewindow ew, wimp_redrawstr *rect, BOOL morerects)
  157.  { sprite_id id;
  158.    os_error  *e = NULL;
  159.    sprite_factors factors;
  160.    sprite_pixtrans pixtrans[256];
  161.    int mode;
  162.  
  163.    id.tag = sprite_id_addr;
  164.    id.s.addr = (char *)ew->area + ew->area->sproff;
  165.    wimp_readpixtrans(ew->area, &id, &factors, pixtrans);
  166.    mode = ((sprite_header *)id.s.addr)->mode;
  167.    if (bbc_modevar(mode, bbc_Log2BPP) == 3)
  168.     { e = colourtran_select_table(mode, 0, -1, (wimp_paletteword *) -1, pixtrans);
  169.     }
  170.    while(morerects && !e)
  171.     { e = sprite_put_scaled(ew->area, &id, 0,
  172.                             rect->box.x0 - rect->scx + ew->workarea.x0,
  173.                             rect->box.y1 - rect->scy + ew->workarea.y0,
  174.                             &factors, pixtrans);
  175.       if (!e)
  176.        { e = wimp_get_rectangle(rect, &morerects);
  177.        }
  178.     }
  179.    wimpt_noerr(e); /* Leave wimpt_noerr until here as it could move the sprite */
  180.  }
  181.  
  182.  
  183. static void ewindow_makesprite(ewindow ew)
  184.  { if (ew->sprite)
  185.     { int size;
  186.       int width, height;
  187.       int mode;
  188.       int dx,dy,bpc,bpp;
  189.  
  190.       if (ew->area)
  191.        { flex_free((flex_ptr)&ew->area);
  192.        }
  193.       mode = (ew->mode == ewindow_smdynamic ? wimpt_mode() : ew->mode);
  194.       dx  = 1<<bbc_modevar(mode, bbc_XEigFactor);
  195.       dy  = 1<<bbc_modevar(mode, bbc_YEigFactor);
  196.       bpc = 1<<bbc_modevar(mode, bbc_Log2BPC);
  197.       bpp = 1<<bbc_modevar(mode, bbc_Log2BPP);
  198.       width  = (ew->workarea.x1-ew->workarea.x0 + dx-1)/dx;
  199.       height = (ew->workarea.y1-ew->workarea.y0 + dy-1)/dy;
  200.       size = ((width*bpc+7)/8+3)/4; /* Size of horizontal line in words */
  201.       size = height*size*4 + sizeof(sprite_header)+sizeof(sprite_area);
  202.       if (flex_alloc((flex_ptr)&ew->area, size))
  203.        { sprite_area_initialise(ew->area, size);
  204.          if (!wimpt_complain(sprite_create(ew->area, "s", FALSE, width, height, mode)))
  205.           { ew->info->timeout = ew->timeout;
  206.             ewindow_drawsprite(ew);
  207.           }
  208.          else
  209.           { ewindow_removesprite(ew);
  210.           }
  211.        }
  212.     }
  213.  }
  214.  
  215. static void ewindow_drawsprite(ewindow ew)
  216.  { if (ew->area)
  217.     { ewindow_spritedrawfinish(ew);
  218.       ewindow_spritedrawsetup(ew);
  219.     }
  220.  }
  221.  
  222.  
  223. static void ewindow_removesprite(ewindow ew)
  224.  { if (ew->area)
  225.     { BOOL update;
  226.  
  227.       flex_free((flex_ptr)&ew->area);
  228.       update = ew->drawing;
  229.       ewindow_spritedrawremoveall(ew);
  230.       ew->info->timeout = 0;
  231.       if (update || (ew->mode != ewindow_smdynamic && ew->mode != wimpt_mode()))
  232.        { ewindow_update(ew);
  233.        }
  234.     }
  235.  }
  236.  
  237.  
  238. /******* sprite draw process *******/
  239.  
  240.  
  241. static void ewindow_spritedrawstart(void *d, void *handle)
  242.  { ewindow ew = handle;
  243.  
  244.    d = d;
  245.    assert(ew->area);
  246.    ew->drawspritewait = FALSE;
  247.    ew->drawing = TRUE;
  248.    ew->firsttime = TRUE;
  249.    ew->currenty = ew->workarea.y1-ew->workarea.y0;
  250.    ew->info->xoffset = -ew->workarea.x0;
  251.    ew->info->yoffset = -ew->workarea.y0;
  252.    ewindow_spritedrawcontinue(0,handle);
  253.  }
  254.  
  255.  
  256. static void ewindow_spritedrawcontinue(int time, void *handle)
  257.  { ewindow ew = handle;
  258.  
  259.    time=time;
  260.    if (wimpt_complain(esprite_draw(&ew->area, ew->area->sproff, ew->info)))
  261.     { ewindow_removesprite(ew);
  262.       ewindow_euclidupdate(ew);
  263.     }
  264.    else
  265.     { wimp_redrawstr r;
  266.       BOOL       more;
  267.       int        nexty;
  268.  
  269.       nexty = (ew->info->timedout ? ew->info->infoblock->nexty : -4);
  270.       r.w = ew->handle;
  271.       r.box.x0 = ew->workarea.x0;
  272.       r.box.x1 = ew->workarea.x1;
  273.       r.box.y0 = nexty + ew->workarea.y0+4;
  274.       r.box.y1 = ew->currenty + ew->workarea.y0+4;
  275.       wimpt_noerr(wimp_update_wind(&r, &more));
  276.       ewindow_redrawloopsprite(ew, &r, more);
  277.  
  278.       if (ew->info->timedout)
  279.        { ew->currenty = nexty;
  280.          alarm_set(alarm_timenow()+ew->drawgap, ewindow_spritedrawcontinue, ew);
  281.        }
  282.       else
  283.        { ewindow_spritedrawfinish(ew);
  284.        }
  285.     }
  286.  }
  287.  
  288.  
  289. static void ewindow_spritedrawfinish(ewindow ew)
  290.  { if (ew->drawing)
  291.     { cache_finished(ew->cache);
  292.       if (ew->info->timedout)
  293.        { edraw_stop(ew->info);
  294.        }
  295.       alarm_removeall(ew);
  296.       ew->drawing = FALSE;
  297.     }
  298.  }
  299.  
  300.  
  301. static void ewindow_spritedrawsetup(ewindow ew)
  302.  { if (!ew->drawspritewait)
  303.     { ew->drawspritewait = TRUE;
  304.       if (!cache_callwhenfree(ew->cache, ewindow_spritedrawstart, ew))
  305.        { ewindow_redrawerror(ew);
  306.          ew->drawspritewait = FALSE;
  307.        }
  308.     }
  309.  }
  310.  
  311.  
  312. static void ewindow_spritedrawremoveall(ewindow ew)
  313.  { if (ew->drawspritewait)
  314.     { ew->drawspritewait = FALSE;
  315.       cache_removeallprocesses(ew->cache, ew); /* A bit OTT, but OK for now */
  316.     }
  317.    ewindow_spritedrawfinish(ew);
  318.  }
  319.  
  320.  
  321. /******* Code for euclid-drawn windows *******/
  322.  
  323. static void ewindow_euclidupdate(ewindow ew)
  324.  { wimp_redrawstr r;
  325.    BOOL           more;
  326.  
  327.    r.w = ew->handle;
  328.    r.box = ew->workarea;
  329.    wimpt_noerr(wimp_update_wind(&r, &more));
  330.    ewindow_redrawloop(ew, &r, more, TRUE);
  331.  }
  332.  
  333. static void ewindow_redrawloopeuclid(ewindow ew, wimp_redrawstr *rect, BOOL morerects,
  334.                                      BOOL update)
  335.  { if (ew->redrawwait || cache_inuse(ew->cache))
  336.     { /* No cache to draw the picture with - blank it and redraw later */
  337.       wimp_setcolour(0);
  338.       while(morerects)
  339.        { if (!update)
  340.           { bbc_clg();
  341.           }
  342.          wimpt_noerr(wimp_get_rectangle(rect, &morerects));
  343.        }
  344.       ewindow_delayedredrawsetup(ew);
  345.     }
  346.    else
  347.     { ewindow_redrawloopeuclidcacheok(ew, rect, morerects);
  348.     }
  349.  }
  350.  
  351.  
  352. static void ewindow_redrawloopeuclidcacheok(ewindow ew, wimp_redrawstr *rect,
  353.                                             BOOL morerects)
  354.  { if (ew->info->structure->cache)
  355.     { *((unsigned int *)ew->info->structure->cache + 1) = 0;
  356.     }
  357.    while(morerects)
  358.     { ew->info->xoffset = rect->box.x0-rect->scx;
  359.       ew->info->yoffset = rect->box.y1-rect->scy;
  360.       wimpt_complain(edraw_split(ew->info));
  361.       wimpt_noerr(wimp_get_rectangle(rect, &morerects));
  362.     }
  363.  }
  364.  
  365.  
  366. /***** delayed redraw process *****/
  367.  
  368. static void ewindow_delayedredrawstart(void *d, void *handle)
  369.  { ewindow ew = handle;
  370.    wimp_redrawstr r;
  371.    BOOL           more;
  372.  
  373.    d=d;
  374.    assert(!ew->area);
  375.    ew->redrawwait = FALSE;
  376.    r.w = ew->handle;
  377.    r.box = ew->workarea;
  378.    wimpt_noerr(wimp_update_wind(&r, &more));
  379.    ewindow_redrawloopeuclidcacheok(ew, &r, more);
  380.    cache_finished(ew->cache);
  381.  }
  382.  
  383.  
  384. static void ewindow_delayedredrawsetup(ewindow ew)
  385.  { if (!ew->redrawwait)
  386.     { ew->redrawwait = TRUE;
  387.       if (!cache_callwhenfree(ew->cache, ewindow_delayedredrawstart, ew))
  388.        { ewindow_redrawerror(ew);
  389.          ew->redrawwait = FALSE;
  390.        }
  391.     }
  392.  }
  393.  
  394. static void ewindow_delayedredrawremoveall(ewindow ew)
  395.  { if (ew->redrawwait)
  396.     { ew->redrawwait = FALSE;
  397.       cache_removeallprocesses(ew->cache, ew); /* A bit OTT, but OK for now */
  398.     }
  399.  }
  400.  
  401.  
  402. /********* Code for redrawing a window ********/
  403.  
  404. static void ewindow_redrawerror(ewindow ew)
  405.  { char error[256];
  406.    sprintf(error, "Unable to redraw window '%s'.",ew->title);
  407.    werr(ERR_NonFatal, error);
  408.  }
  409.  
  410. static void ewindow_redraw(ewindow ew)
  411.  { wimp_redrawstr rect;
  412.    BOOL           morerects;
  413.  
  414.    rect.w = ew->handle;
  415.    wimpt_noerr(wimp_redraw_wind(&rect, &morerects));
  416.    ewindow_redrawloop(ew, &rect, morerects, FALSE);
  417.  }
  418.  
  419. static void ewindow_redrawloop(ewindow ew, wimp_redrawstr *rect, BOOL morerects,
  420.                                                                  BOOL update)
  421.  { if (ew->area)
  422.     { ewindow_redrawloopsprite(ew, rect, morerects);
  423.     }
  424.    else
  425.     { ewindow_redrawloopeuclid(ew, rect, morerects, update);
  426.     }
  427.  }
  428.  
  429.  
  430. /******** Handle wimp events ********/
  431.  
  432. static void ewindow_handler(wimp_eventstr *e, void *info)
  433.  { ewindow ew = info;
  434.  
  435.    switch(e->e)
  436.     { case wimp_EREDRAW: ewindow_redraw((ewindow)info);            break;
  437.       case wimp_EOPEN:   wimpt_noerr(wimp_open_wind(&e->data.o));  break;
  438.       case wimp_ECLOSE:  ew->closefn(ew, ew->closehandle);         break;
  439.     }
  440.  }
  441.  
  442.  
  443. #define ewindow_spriteaddr(ew) ((sprite_header *)(char *)(ew)->area + (ew)->area->sproff)
  444.  
  445. static BOOL ewindow_unknownhandler(wimp_eventstr *e, void *info)
  446.  { ewindow ew = info;
  447.  
  448.    switch(e->e)
  449.     { case wimp_ESEND:
  450.       case wimp_ESENDWANTACK:
  451.         switch(e->data.msg.hdr.action)
  452.          { case wimp_MMODECHANGE:
  453.              wimpt_checkmode();
  454.              if ((ew->area && ew->mode == ewindow_smdynamic &&
  455.                   ewindow_spriteaddr(ew)->mode != wimpt_mode()) ||
  456.                  (ew->sprite && !ew->area))
  457.               { ewindow_makesprite(ew);
  458.               }
  459.             break;
  460.            case wimp_PALETTECHANGE:
  461.              euclid_invalidatepalettecache();
  462.              if (ew->area &&
  463.                  (ew->info->style & (emainstyle_raytrace*edrawstyle_mainstyle)))
  464.               { ewindow_redrawsprite(ew);
  465.               }
  466.              else
  467.               { ewindow_update(ew);
  468.               }
  469.              break;
  470.          }
  471.     }
  472.    return(FALSE); /* Allow other windows a chance to see events */
  473.  }
  474.  
  475.  
  476.  
  477. /******** Create and manipulate windows ********/
  478.  
  479. ewindow ewindow_create(const char *title, euclid_drawstyle style,
  480.                        euclid_header *structure, const char *camera,
  481.                        ewindow_closefn cfn, void *handle)
  482.  { ewindow    ew;
  483.    edraw_info *info;
  484.    wimp_wind  *window;
  485.  
  486.    if ((window = template_syshandle("ewindow")) == NULL)
  487.     { werr(ERR_NonFatal, "Template 'ewindow' not found");
  488.       return(NULL);
  489.     }
  490.    window->titleflags |= wimp_INDIRECT;
  491.    window->title.indirecttext.buffer = (char *)title;
  492.    if ((ew = malloc(sizeof(*ew))) == NULL)
  493.     { return(NULL);
  494.     }
  495.    if ((info = malloc(sizeof(*info))) == NULL)
  496.     { free(ew);
  497.       return(NULL);
  498.     }
  499.    if (wimpt_complain(wimp_create_wind(window, &ew->handle)) != 0)
  500.     { free(info);
  501.       free(ew);
  502.       return(NULL);
  503.     }
  504.    edraw_initialise(info);
  505.    info->structure = structure;
  506.    info->camera    = camera;
  507.    info->style     = style & 0x7ff;
  508.    info->timeout   = 0;
  509.  
  510.    ew->info           = info;
  511.    ew->title          = title;
  512.    ew->closefn        = cfn;
  513.    ew->closehandle    = handle;
  514.    ew->workarea       = window->ex;
  515.    ew->cache          = cache_address(structure);
  516.    ew->timeout        = 0;
  517.    ew->sprite         = FALSE;
  518.    ew->area           = NULL;
  519.    ew->drawspritewait = FALSE;
  520.    ew->drawing        = FALSE;
  521.    ew->redrawwait     = FALSE;
  522.    ew->freesprite     = TRUE;
  523.    win_register_event_handler(ew->handle, ewindow_handler, ew);
  524.    win_add_unknown_event_processor(ewindow_unknownhandler, ew);
  525.    wimpt_checkmode();
  526.    return(ew);
  527.  }
  528.  
  529.  
  530. void ewindow_usesprite(ewindow ew, BOOL sprite, ewindow_spritemode mode)
  531.  { ew->sprite = sprite;
  532.  
  533.    if (sprite)
  534.     { if (mode == ewindow_smcurrent)
  535.        { mode = wimpt_mode();
  536.        }
  537.       if (!ew->area || mode != ew->mode)
  538.        { if (!ew->area)
  539.           { ewindow_delayedredrawremoveall(ew);
  540.           }
  541.          ew->mode = mode;
  542.          ewindow_makesprite(ew);
  543.        }
  544.     }
  545.    else
  546.     { if (ew->area)
  547.        { ewindow_removesprite(ew);
  548.        }
  549.     }
  550.  }
  551.  
  552. void ewindow_timing(ewindow ew, char timeout, unsigned int drawgap)
  553.  { ew->timeout = timeout;
  554.    ew->drawgap = drawgap;
  555.    if (ew->area)
  556.     { ew->info->timeout = timeout;
  557.     }
  558.  }
  559.  
  560. void ewindow_setstyle(ewindow ew, euclid_drawstyle style)
  561.  { style &= 0x7ff;
  562.  
  563.    if (ew->info->style != style)
  564.     { ew->info->style = style;
  565.       ewindow_update(ew);
  566.     }
  567.  }
  568.  
  569.  
  570. void ewindow_open(ewindow ew)
  571.  { wimp_wstate wstate;
  572.  
  573.    wimpt_noerr(wimp_get_wind_state(ew->handle, &wstate));
  574.    wstate.o.behind = -1;
  575.    wimpt_noerr(wimp_open_wind(&wstate.o));
  576.    if (!ew->area)
  577.     { ewindow_makesprite(ew);
  578.     }
  579.  }
  580.  
  581. void ewindow_closeoptions(ewindow ew, BOOL freesprite)
  582.  { ew->freesprite = freesprite;
  583.  }
  584.  
  585. BOOL ewindow_hassprite(ewindow ew)
  586.  { return(ew->area != NULL);
  587.  }
  588.  
  589. BOOL ewindow_sprite(ewindow ew, sprite_area ***area, int *offset)
  590.  { *area = &ew->area;
  591.    *offset = ew->area->sproff;
  592.    return(ew->area != NULL);
  593.  }
  594.  
  595. BOOL ewindow_updatecomplete(ewindow ew)
  596.  { return(!ew->drawing && !ew->drawspritewait && !ew->redrawwait);
  597.  }
  598.  
  599.  
  600. void ewindow_update(ewindow ew)
  601.  { if (ew->area)
  602.     { ewindow_drawsprite(ew);
  603.     }
  604.    else
  605.     { ewindow_euclidupdate(ew);
  606.     }
  607.  }
  608.  
  609.  
  610. void ewindow_close(ewindow ew)
  611.  { wimpt_noerr(wimp_close_wind(ew->handle));
  612.    if (ew->area && ew->freesprite)
  613.     { ewindow_removesprite(ew);
  614.     }
  615.    if (!ew->area)
  616.     { ewindow_delayedredrawremoveall(ew);
  617.     }
  618.  }
  619.  
  620. void ewindow_destroy(ewindow ew)
  621.  { win_register_event_handler(ew->handle, NULL, NULL);
  622.    win_remove_unknown_event_processor(ewindow_unknownhandler, ew);
  623.    wimpt_noerr(wimp_delete_wind(ew->handle));
  624.    ewindow_removesprite(ew);
  625.    ewindow_delayedredrawremoveall(ew);
  626.    free(ew);
  627.  }
  628.  
  629. wimp_w ewindow_handle(ewindow ew)
  630.  { return(ew->handle);
  631.  }
  632.